//
// Created by denglibin on 2021/4/16.
//

#include "double_link_list.h"
#include "stdlib.h"
#include "stdio.h"
/**
 * 创建节点
 * @param key
 * @param value
 * @return
 */
Node* createNode(int key, int value){
    Node* node = (Node*)calloc(1, sizeof(Node));
    node->key = key;
    node->value = value;
    return node;
}

/**
 * 打印
 * @param node
 */
void printNode(Node* node){
    printf("key = %d, value = %d\n", node->key, node->value);
}

/**
 * 释放节点
 * @param node
 */
void freeNode(Node* node){
    free(node);
}

/**
 * 创建
 * @param capacity
 * @return
 */
DoubleLinkList * createDoubleLinkList(int capacity){
    DoubleLinkList * list = (DoubleLinkList*)calloc(1, sizeof (DoubleLinkList));
    list->capacity = capacity;
    list->size = 0;
    return list;
}
/**
 * 打印
 * @param doubleLinkList
 */
void printList(DoubleLinkList* doubleLinkList){
    Node* temp = doubleLinkList->head;
    while (temp){
        printNode(temp);
        temp = temp->next;
    }
}
/**
 * 头部添加节点
 * @param doubleLinkList
 * @param node
 */
void insertHead(DoubleLinkList* doubleLinkList, Node* node){

    //已经有头部节点
    if(doubleLinkList->head){
        doubleLinkList->head->prev = node;
        node->next = doubleLinkList->head;
        doubleLinkList->head = node;
    }else {
        //没有头部节点
        doubleLinkList->head = node;
        doubleLinkList->tail = node;
    }
    //大小+1
    doubleLinkList->size++;
}

/**
 * 尾部添加节点
 * @param doubleLinkList
 * @param node
 */
void insertTail(DoubleLinkList* doubleLinkList, Node* node){
    //有尾部节点
    if(doubleLinkList->tail){
        doubleLinkList->tail->next = node;
        node->prev = doubleLinkList->tail;
        doubleLinkList->tail = node;
    }else{
        doubleLinkList->tail = node;
        doubleLinkList->head = node;
    }
    doubleLinkList->size++;

}

/**
 * 移除节点
 * @param doubleLinkList
 * @param node 移除的节点（为NULL则移除尾部节点）
 */
void removeNode(DoubleLinkList* doubleLinkList, Node* node){
    if(doubleLinkList->size == 0){
        return;
    }
    if(node == NULL){
        node = doubleLinkList->tail;
    }
    if(node == doubleLinkList->head){
        removeHead(doubleLinkList);
        return;
    }
    if(node == doubleLinkList->tail){
        removeTail(doubleLinkList);
        return;
    }
    Node * pre = node->prev;
    Node * next = node->next;
    freeNode(node);
    pre->next = next;
    next->prev = pre;
    doubleLinkList->size--;

}
/**
 * 移除尾部
 * @param doubleLinkList
 */
void removeTail(DoubleLinkList* doubleLinkList){
    if(doubleLinkList->size == 0){
        return;
    }
    if(doubleLinkList->size == 1){
        freeNode(doubleLinkList->tail);
        doubleLinkList->head = NULL;
        doubleLinkList->tail = NULL;
    }else {
        Node* tailPrev = doubleLinkList->tail->prev;
        freeNode(doubleLinkList->tail);
        tailPrev->next = NULL;
        doubleLinkList->tail = tailPrev;
    }

    doubleLinkList->size--;
}

/**
 * 移除头部
 * @param doubleLinkList
 */
void removeHead(DoubleLinkList* doubleLinkList){
    if(doubleLinkList->size == 0){
        return;
    }
    if(doubleLinkList->size == 1){
        freeNode(doubleLinkList->tail);
        doubleLinkList->head = NULL;
        doubleLinkList->tail = NULL;
    }else {
        Node* headNext = doubleLinkList->head->next;
        freeNode(doubleLinkList->head);
        headNext->prev = NULL;
        doubleLinkList->head = headNext;
    }

    doubleLinkList->size--;
}

/**
 * 弹出头部节点
 * @param doubleLinkList
 * @return
 */
Node * popHead(DoubleLinkList* doubleLinkList){
    if(doubleLinkList->size == 0){
        return NULL;
    }
    Node* head = doubleLinkList->head;
    if(doubleLinkList->size == 1){
        doubleLinkList->head = NULL;
        doubleLinkList->tail = NULL;
    }else {
        doubleLinkList->head = head->next;
        doubleLinkList->head->prev = NULL;
    }

    doubleLinkList->size--;
    return head;

}
/**
 * 弹出尾部节点
 * @param doubleLinkList
 * @return
 */
Node * popTail(DoubleLinkList* doubleLinkList){
    if(doubleLinkList->size == 0){
        return NULL;
    }
    Node* tail = doubleLinkList->tail;
    if(doubleLinkList->size == 1){
        doubleLinkList->head = NULL;
        doubleLinkList->tail = NULL;
    }else {
        doubleLinkList->tail = tail->prev;
        doubleLinkList->tail->next = NULL;
    }

    doubleLinkList->size--;
    return tail;
}
/**
 * 释放
 * @param doubleLinkList
 */
void freeDoubleLinkList(DoubleLinkList* doubleLinkList){
    Node * temp = doubleLinkList->head;
    while (temp){
        freeNode(temp);
        temp = temp->next;
    }

    free(doubleLinkList);
}